#ifndef __USERTYPE_H__
#define __USERTYPE_H__

#include "env.h"


/**************************************************************************************************************
 _wserVector是一个变长的数组，使用前请一定记得调用resize函数用来初始化。
 包含以下成员函数：
  1.void resize(int);					用来初始化数组的大小，每一次resize都会引起数据强行重置。
  2.void clear();						清空整个数组。
  3.void copy(const _wserVector<V>&);	复制整个_wserVector数组。
  4.void copy(const std::vector<V>&);	将STL的vector复制到_wserVector中。
  5.int find(V);						查找在数组中是否存在value相同的数据。如果有，返回下标；如果没有，返回-1。
  6.void push_back(V);					找最近的一个空位添加元素。
  7.bool push_back_distinct(V);			在保证不重复的情况下找最近的空位添加元素。
  8.void set(int, V);					在指定的数组位置存入元素，如果位置小于0，等同于push_back。
  9.void erase(int);					删除指定位置的元素。
 10.int length() const;					返回当前占用的数组长度。
 11.int size() const;					返回初始化时的数组总长度。
 12.bool check(int);					检查当前位置是否被占用。
 **************************************************************************************************************/

template <class V>
class _wserVector {
private:
	V* _valuelist;bool* _flaglist;int __size, __length, __nextempty;
	pthread_mutex_t lock;
public:
	_wserVector<V>() {
		_valuelist = 0;_flaglist = 0;__size = __length = __nextempty = 0;
		pthread_mutex_init(&lock, 0);
	}
	void resize(int size) {
		if (size > 0) {
			if (_valuelist) {delete _valuelist;_valuelist = 0;}
			if (_flaglist) {delete _flaglist;_flaglist = 0;}
			_valuelist = new V[size];_flaglist = new bool[size];
			memset(_flaglist, 0, size*sizeof(bool));
			__size = size;__length = __nextempty = 0;
		}
		else {
			if (_valuelist) {delete _valuelist;_valuelist = 0;}
			if (_flaglist) {delete _flaglist;_flaglist = 0;}
			__size = __length = __nextempty = 0;
		}
	}
	~_wserVector() {
		if (_flaglist != 0) {
			delete[] _flaglist;_flaglist = 0;
		}
		if (_valuelist) {
			delete[] _valuelist;_valuelist = 0;
		}
		__size = __length = 0;__nextempty = -1;
		pthread_mutex_destroy(&lock);
	}
public:
	void clear() {
		pthread_mutex_lock(&lock);
		for (int i = 0;i < __size;i++) {
			_flaglist[i] = 0;
		}
		__length = 0;__nextempty = 0;
		pthread_mutex_unlock(&lock);
	}
	void copy(const _wserVector<V>& vec) {
		pthread_mutex_lock(&lock);
		__length = vec.__length;__nextempty = vec.__nextempty;
		for (int i = 0;i < vec.__size;i++) {
			_valuelist[i] = vec._valuelist[i];_flaglist[i] = vec._flaglist[i];
		}
		pthread_mutex_unlock(&lock);
	}
	void copy(const std::vector<V>& vec) {
		pthread_mutex_lock(&lock);
		__length = vec.size();
		int i;
		for (i = 0;i < vec.size();i++) {
			_valuelist[i] = vec[i];_flaglist[i] = true;
		}
		__nextempty = i;
		pthread_mutex_unlock(&lock);
	}
	int find(V v) {
		for (int i = 0;i < __size;i++) {
			if (_flaglist[i] == false) continue;
			if (_valuelist[i] == v) return i;
		}
		return -1;
	}
	void set(int pos, V v) {
		if (pos >= 0) {
			pthread_mutex_lock(&lock);
			_valuelist[pos] = v;
			if (!_flaglist[pos]) __length++;
			_flaglist[pos] = true;
			if (pos == __nextempty) findempty();
			pthread_mutex_unlock(&lock);
		}
		else if (pos < 0) {
			push_back(v);
		}
	}
	void push_back(V v) {
		if (__nextempty == -1) findempty();
		if (__nextempty == -1) return;
		pthread_mutex_lock(&lock);
		_flaglist[__nextempty] = true;_valuelist[__nextempty] = v;__length++;
		pthread_mutex_unlock(&lock);
		findempty();
	}
	bool push_back_distinct(V v) {
		int pos = find(v);
		if (pos < 0) {push_back(v);return true;}
		return false;
	}
	void erase(int pos) {
		pthread_mutex_lock(&lock);
		_flaglist[pos] = false;__length--;
		pthread_mutex_unlock(&lock);
	}
	V& operator[] (int pos) const {return _valuelist[pos];}
	int length() const {return __length;}
	int size() const {return __size;}
	bool check(int pos) {return _flaglist[pos];}
	void findempty() {
		int start = __nextempty;__nextempty = -1;
		for (int i = start+1;i < __size;i++) {
			if (!_flaglist[i]) {__nextempty = i;return;}
		}
		for (int i = 0;i < start;i++) {
			if (!_flaglist[i]) {__nextempty = i;return;}
		}
	}
};


/**************************************************************************************************************
 _wserMap是一个变长的字典，使用前请一定记得调用resize函数用来初始化。
 包含以下成员函数：
  1.void resize(int);					用来初始化字典的大小，每一次resize都会引起数据强行重置。
  2.void clear();						清空整个数组。
  3.void copy(const _wserVector<T, V>&);复制整个_wserMap字典。
  4.void copy(const std::map<T, V>&);	将STL的map复制到_wserMap中。
  5.int find(T);						查找在字典中是否存在某个key。如果有，返回下标；如果没有，返回-1。
  6.void set(T, V);						复制某个key对应的value。
  7.V& locate(int);						返回某个位置的key。
  8.T& locatetype(int);					返回某个位置的value。
  9.void erase(int);					删除指定位置的元素。
 10.void remove(T);						删除某个key。
 11.int length() const;					返回当前占用的字典长度。
 12.int size() const;					返回初始化时的字典总长度。
 13.bool check(int);					检查当前位置是否被占用。
 **************************************************************************************************************/

template <class T, class V>
class _wserMap {
private:
	T* _typelist;V* _valuelist;bool* _flaglist;int __size, __length, __nextempty;
	pthread_mutex_t lock;
public:
	_wserMap<T, V>() {
		_typelist = 0;_valuelist = 0;_flaglist = 0;__size = __length = __nextempty = 0;
		pthread_mutex_init(&lock, 0);
	}
	void resize(int size) {
		pthread_mutex_lock(&lock);
		if (size > 0) {
			_typelist = new T[size];_valuelist = new V[size];_flaglist = new bool[size];memset(_flaglist, 0, size*sizeof(bool));__size = size;__length = __nextempty = 0;
		}
		else {
			_typelist = 0;_valuelist = 0;_flaglist = 0;__size = __length = __nextempty = 0;
		}
		pthread_mutex_unlock(&lock);
	}
	~_wserMap() {
		if (_flaglist != 0) {
			delete[] _flaglist;_flaglist = 0;
		}
		if (_typelist != 0) {
			delete[] _typelist;_typelist = 0;
		}
		if (_valuelist) {
			delete[] _valuelist;_valuelist = 0;
		}
		__size = __length = 0;__nextempty = -1;
		pthread_mutex_destroy(&lock);
	}
public:
	void clear() {
		pthread_mutex_lock(&lock);
		for (int i = 0;i < __size;i++) {
			_flaglist[i] = 0;
		}
		__length = 0;__nextempty = 0;
		pthread_mutex_unlock(&lock);
	}
	void copy(const _wserMap<T, V>& map) {
		pthread_mutex_lock(&lock);
		__length = map.__length;__nextempty = map.__nextempty;
		for (int i = 0;i < map.__size;i++) {
			_typelist[i] = map._typelist[i];_valuelist[i] = map._valuelist[i];_flaglist[i] = map._flaglist[i];
		}
		pthread_mutex_unlock(&lock);
	}
	void copy(const std::map<T, V>& map) {
		pthread_mutex_lock(&lock);
		__length = map.size();int i = 0;
		for (typename std::map<T, V>::iterator iter = map.begin(); iter != map.end();iter++) {
			_typelist[i] = iter->first;_valuelist[i] = iter->second;_flaglist[i] = true;i++;
		}
		__nextempty = i;
		pthread_mutex_unlock(&lock);
	}
	int find(T t) {
		for (int i = 0;i < __size;i++) {
			if (!_flaglist[i] ) continue;
			if (_typelist[i] == t) return i;
		}
		return -1;
	}
	void findempty() {
		int start = __nextempty;__nextempty = -1;
		for (int i = start+1;i < __size;i++) {
			if (!_flaglist[i]) {__nextempty = i;return;}
		}
		for (int i = 0;i < start;i++) {
			if (!_flaglist[i]) {__nextempty = i;return;}
		}
	}
	void set(T t, V v) {
		int pos = find(t);
		if (pos >= 0) {
			pthread_mutex_lock(&lock);
			_typelist[pos] = t;_valuelist[pos] = v;_flaglist[pos] = true;
			pthread_mutex_unlock(&lock);
		}
		else if (pos < 0) {
			if (__nextempty == -1) findempty();
			if (__nextempty == -1) return;
			pthread_mutex_lock(&lock);
			_typelist[__nextempty] = t;_valuelist[__nextempty] = v;_flaglist[__nextempty] = true;__length++;findempty();
			pthread_mutex_unlock(&lock);
		}
	}
	V& locate(int pos) {return _valuelist[pos];}
	T& locatetype(int pos) {return _typelist[pos];}
	void erase(T t) {
		int pos = find(t);
		if (pos > 0) {
			pthread_mutex_lock(&lock);
			_flaglist[pos] = false;__length--;
			pthread_mutex_unlock(&lock);
		}
	}
	void remove(int pos) {
		pthread_mutex_lock(&lock);
		_flaglist[pos] = false;__length--;
		pthread_mutex_unlock(&lock);
	}
	int length() {return __length;}
	int size() {return __size;}
	bool check(int pos) {return _flaglist[pos];}
};


extern std::string hex2str(std::string hex);
extern std::string str2hex(std::string str);

#endif //__USERTYPE_H__
